package com.hyper_yang._01_jdbc.prob;

import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
    MySQL中事务的控制:
        1.设置当前连接的事务提交为手动提交
            set autocommit = false;
        2.事务执行成功，提交事务
            commit;
        3.事务执行失败，回滚事务
            rollback;
 */
public class TransactionTest {

    @Test
    public void testTransaction() {
        // 1.注册驱动
        // Class.forname("com.mysql.cj.jdbc.Driver"); 执行类加载 （执行静态代码块）注册 Driver

        // finally:
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        PreparedStatement preparedStatement1 = null;

        try {
            // 2.获取连接
            connection = DriverManager.getConnection("jdbc:mysql:///test1", "root", "abc123");

            // todo: 事务的控制: 将连接设置为手动提交
            connection.setAutoCommit(false);
            // 3.准备 sql
            String sql = "update t_account set balance = balance - ? where id = ?";
            // 4.创建发送器
            preparedStatement = connection.prepareStatement(sql);
            // 4.1 占位符赋值
            preparedStatement.setObject(1, 1000);
            preparedStatement.setObject(2, 4);
            preparedStatement.executeUpdate();

            // 出现异常
//            int i = 10 / 0;

            // 3.准备 sql
            String sql1 = "update t_account set balance = balance + ? where id = ?";
            // 4.创建发送器
            preparedStatement1 = connection.prepareStatement(sql1);
            // 4.1 占位符赋值
            preparedStatement1.setObject(1, 1000);
            preparedStatement1.setObject(2, 3);
            preparedStatement1.executeUpdate();

            // todo: 事务正确执行完毕，提交
            System.out.println("转账成功");
            connection.commit();
            connection.setAutoCommit(true);
        } catch (SQLException e) {
            System.out.println("出现异常了，原因是" + e.getMessage());
            // todo: 事务执行时出现异常，回滚
            try {
                connection.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally {
            try {
                if (preparedStatement != null) {
                    preparedStatement1.close();
                }
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
